import React, { useEffect, useState } from 'react';
import { Button, List, Modal, Tooltip, Select } from 'antd';
import { useMemoizedFn, useRequest, useSetState } from 'ahooks';
import {
  CopyOutlined,
  DeleteOutlined,
  EditOutlined,
  PlayCircleOutlined,
  PlusOutlined,
} from '@ant-design/icons';
import {
  queryProjects,
  updateProjectById,
  insertProject,
  delProjectById,
  queryCateList,
  addCate,
  updateCate,
  removeCate,
} from '@/services';

import CreateModal from './CreateModal';
import Search from '@/components/Paste/Search';

import LoadMore from './LoadMore';
import './index.less';
import { message } from '@tauri-apps/api/dialog';
import { getCommandKey } from '@/utils';
import { listen } from '@tauri-apps/api/event';
import CreateCateModal from './CreateCateModal';

const { Option } = Select;

let unlistenFlushProjectList: any = null;

interface ProjectListProps {
  onProjectStart: (project: ProjectItem) => void;
  onProjectChange: (project: ProjectItem) => void;
}

const ProjectList: React.FC<ProjectListProps> = ({
  onProjectStart,
  onProjectChange,
}) => {
  const [initLoading, setInitLoading] = useState<boolean>(true);
  const [listData, setListData] = useState<ProjectItem[]>([]);
  const [cateId, setCateId] = useState<number>(0);
  const [keyword, setKeyword] = useState<string | undefined>(undefined);
  const [cateList, setCateList] = useState<CateItem[]>([]);
  const [editData, setEditData] = useState<ProjectItem>();
  const [editCateData, setEditCateData] = useState<CateItem>();
  const [hasMore, setHasMore] = useState<boolean>(true);
  const [total, setTotal] = useState<number>(0);
  const [modalVisible, setModalVisible] = useState<boolean>(false);
  const [createCateVisible, setCreateCateVisible] = useState<boolean>(false);

  const [pageInfo, setPageInfo] = useSetState<PageInfo>({
    pageSize: 1,
    pageNum: 0,
  });
  // 获取项目列表
  const { run: getProjectListRun, loading } = useRequest(
    (keyword?: string) => queryProjects(cateId, keyword),
    {
      manual: true,
      onSuccess(ret: any) {
        if (ret) {
          const { list, total } = ret;
          setTotal(total);
          const datas = list.map((item: ProjectItem) => ({
            ...item,
            commands: item.commands?.map((c) => ({
              ...c,
              key: getCommandKey(item.code as string, c.value),
            })),
          }));
          setListData(datas);
          setHasMore(datas.length < total);
        }
      },
      onFinally() {
        setInitLoading(false);
      },
    },
  );
  // 获取分类列表
  const { run: getCataListRun, loading: cataListLoading } = useRequest(
    queryCateList,
    {
      manual: true,
      onSuccess(ret: any) {
        if (ret) {
          setCateList(ret || []);
        }
      },
    },
  );
  // 保存项目配置
  const { run: save, loading: submitLoading } = useRequest(insertProject, {
    manual: true,
    onSuccess() {
      getProjectListRun();
      setModalVisible(false);
    },
    onError(e) {
      message(e.message, {
        title: '提示',
        type: 'error',
      });
    },
  });
  // 更新项目配置
  const { run: update, loading: updateLoading } = useRequest(
    updateProjectById,
    {
      manual: true,
      onSuccess(proItem: any) {
        onProjectChange(proItem);
        getProjectListRun();
        setModalVisible(false);
      },
      onError(e) {
        message(e.message, {
          title: '提示',
          type: 'error',
        });
      },
    },
  );
  // 删除项目
  const { runAsync: deleteRun } = useRequest(delProjectById, {
    manual: true,
  });
  // 加载更多
  const onLoadMore = useMemoizedFn(() => {
    if (!hasMore || loading) return;
    const { pageNum } = pageInfo;
    setPageInfo({
      pageNum: pageNum + 1,
    });
    return getProjectListRun();
  });
  // 提交项目配置

  const submitProject = async (data: ProjectItem) => {
    if (data.id) {
      update(data);
    } else {
      save(data);
    }
  };
  // 修改或新建分类
  const { runAsync: delCate } = useRequest(removeCate, {
    manual: true,
  });
  const { runAsync: insertCate } = useRequest(addCate, {
    manual: true,
  });
  const { runAsync: modifyCate } = useRequest(updateCate, {
    manual: true,
  });
  const submitCate = async (data: CateItem) => {
    if (data.id) {
      modifyCate(data)
        .then(() => {
          getCataListRun();
          setCreateCateVisible(false);
        })
        .catch((e) => {
          message(e.toString(), { title: '提示', type: 'error' });
        });
    } else {
      insertCate(data)
        .then(() => {
          getCataListRun();
          setCreateCateVisible(false);
        })
        .catch((e) => {
          message(e.toString(), { title: '提示', type: 'error' });
        });
    }
  };

  // 删除项目参数
  const delCateRow = async (data: CateItem) => {
    Modal.confirm({
      title: '删除分类',
      centered: true,
      content: `确认是否删除分类 ${data.name} ?`,
      onOk: () =>
        new Promise(async (resolve, reject) => {
          delCate(data.id as number)
            .then(() => {
              resolve(1);
              getCataListRun();
            })
            .catch(reject);
        }),
    });
  };

  // 复制项目参数
  const copyRow = (data: ProjectItem) => {
    const { id, createTime, updateTime, ...rest } = data;
    setEditData(rest);
    setModalVisible(true);
  };

  // 删除项目参数
  const delRow = async (data: ProjectItem) => {
    Modal.confirm({
      title: '删除项目',
      centered: true,
      content: `确认是否删除项目 ${data.name} ?`,
      onOk: () =>
        new Promise(async (resolve, reject) => {
          deleteRun(data.id as number)
            .then(() => {
              resolve(1);
              getProjectListRun();
            })
            .catch(reject);
        }),
    });
  };

  // 编辑项目参数
  const editRow = (data: ProjectItem) => {
    setEditData(data);
    setModalVisible(true);
  };

  // 启动项目
  const startRow = (data: ProjectItem) => {
    const count = data.count || 0;
    data.count = count + 1;
    onProjectChange(data);
    onProjectStart(data);
  };

  // 过滤项目
  const onKeywrodChange = useMemoizedFn((event: any) => {
    const keyword = typeof event === 'string' ? event : event.target.value;
    setKeyword(keyword);
  });

  useEffect(() => {
    getProjectListRun((keyword || '').trim());
  }, [keyword, cateId]);

  const initListen = async () => {
    unlistenFlushProjectList = await listen<string>('flushProjectList', () => {
      getProjectListRun();
    });
  };

  useEffect(() => {
    getCataListRun();
    initListen();
    return () => {
      unlistenFlushProjectList && unlistenFlushProjectList();
    };
  }, []);

  return (
    <div className="tabs-list-wrapper">
      <div className="tab-list-actions">
        <div className="tab-list-total">共 {total} 个</div>
        <div className="tab-list-actions-btns">
          <Tooltip title="新增项目">
            <Button
              size="small"
              type="primary"
              onClick={() => setModalVisible(true)}
            >
              <PlusOutlined />
            </Button>
          </Tooltip>
        </div>
      </div>
      <div className="tab-list-search">
        <div className="cata-selector">
          <div>分类：</div>
          <Select
            size="small"
            style={{ flex: 1, fontSize: 12, overflow: 'hidden' }}
            placeholder="请选择分类"
            defaultValue={0}
            showSearch
            optionFilterProp="label"
            onChange={(value) => setCateId(value)}
            dropdownRender={(menu) => {
              return (
                <div className="cata-selector-dropdown">
                  {menu}
                  <div
                    style={{
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                    }}
                  >
                    <Button
                      size="small"
                      type="link"
                      onClick={() => setCreateCateVisible(true)}
                      style={{ cursor: 'pointer' }}
                    >
                      <PlusOutlined /> 新增分类
                    </Button>
                  </div>
                </div>
              );
            }}
          >
            <Option value={0}>全部</Option>
            {cateList.map((item) => (
              <Option key={item.id} value={item.id} label={item.name}>
                <div className="cate-list-option">
                  <div className="cate-list-option-label" title={item.name}>
                    {item.name}
                  </div>
                  <div className="cate-list-option-actions">
                    <a
                      onClick={() => {
                        setEditCateData(item);
                        setCreateCateVisible(true);
                      }}
                    >
                      <Tooltip title="编辑">
                        <EditOutlined />
                      </Tooltip>
                    </a>
                    <a onClick={() => delCateRow(item)}>
                      <Tooltip title="删除">
                        <DeleteOutlined />
                      </Tooltip>
                    </a>
                  </div>
                </div>
              </Option>
            ))}
          </Select>
        </div>
        <Search value={keyword} onChange={onKeywrodChange} allowClear />
      </div>
      <div id="scrollableDiv" className="tabs-list">
        {!initLoading && (
          <List
            className="tabs-loadmore-list"
            itemLayout="horizontal"
            dataSource={listData}
            renderItem={(item: ProjectItem) => (
              <List.Item key={item.index}>
                <List.Item.Meta
                  title={
                    <span
                      dangerouslySetInnerHTML={{
                        __html: `${item.tagName}(${item.tagCode})`,
                      }}
                    ></span>
                  }
                  style={{ wordBreak: 'break-all', paddingRight: 10 }}
                  description={
                    <div>
                      <div
                        style={{
                          fontSize: 12,
                        }}
                      >
                        <span
                          dangerouslySetInnerHTML={{
                            __html: item.tagDescription || '',
                          }}
                        ></span>
                      </div>
                      <div
                        style={{
                          padding: 5,
                          display: 'flex',
                          alignItems: 'center',
                          justifyContent: 'space-between',
                        }}
                      >
                        <a
                          key="list-loadmore-start"
                          onClick={() => startRow(item)}
                        >
                          <Tooltip title="启动">
                            <PlayCircleOutlined />
                          </Tooltip>
                        </a>
                        <a
                          key="list-loadmore-edit"
                          onClick={() => editRow(item)}
                        >
                          <Tooltip title="编辑">
                            <EditOutlined />
                          </Tooltip>
                        </a>
                        <a
                          key="list-loadmore-copy"
                          onClick={() => copyRow(item)}
                        >
                          <Tooltip title="复制">
                            <CopyOutlined />
                          </Tooltip>
                        </a>
                        <a key="list-loadmore-del" onClick={() => delRow(item)}>
                          <Tooltip title="删除">
                            <DeleteOutlined />
                          </Tooltip>
                        </a>
                      </div>
                    </div>
                  }
                />
              </List.Item>
            )}
          />
        )}
        <LoadMore hasMore={hasMore} loading={loading} onLoadMore={onLoadMore} />
      </div>
      <CreateModal
        cateList={cateList}
        visible={modalVisible}
        onCancel={() => {
          setModalVisible(false);
          setEditData(undefined);
        }}
        onOk={submitProject}
        data={editData}
        loading={submitLoading || updateLoading}
      ></CreateModal>
      <CreateCateModal
        visible={createCateVisible}
        onCancel={() => {
          setCreateCateVisible(false);
          setEditCateData(undefined);
        }}
        onOk={submitCate}
        data={editCateData}
      />
    </div>
  );
};

export default ProjectList;
